#include "keyboardmanager.h"

using namespace std;

//For readability
#define Key WPARAM

map<Key, bool> KeyboardManager::PrevKeyStates = map<Key, bool>();
map<Key, bool> KeyboardManager::KeyStates = map<Key, bool>();

void KeyboardManager::Init(){
	//PrevKeyStates = map<Key, bool>();
	//KeyStates = map<Key, bool>();
}

void KeyboardManager::Update(){
	PrevKeyStates.clear();
	for (pair<Key, bool> entry : KeyStates) {
		PrevKeyStates[entry.first] = entry.second;
	}
}

void KeyboardManager::KeyDown(Key key){
	KeyStates[key] = true;
}

void KeyboardManager::KeyUp(Key key){
	KeyStates[key] = false;
}

/* Key Checking */
bool KeyboardManager::IsDown(Key key){
	if (ContainsKey(KeyStates, key)){
		return KeyStates[key];
	} else {
		return false;
	}
}

vector<Key> KeyboardManager::GetAllDownKeys(){
	vector<Key> l;

	for (pair<Key, bool> kvp : KeyStates) {
		if (IsDown(kvp.first)) {
			l.push_back(kvp.first);
		}
	}

	return l;
}

bool KeyboardManager::IsPressed(Key key){
	if(ContainsKey(PrevKeyStates, key) && PrevKeyStates[key]) { //If it was previously down
		return false;
	} else if(ContainsKey(KeyStates, key) && KeyStates[key]) { //Previously up & is currently down
		return true;
	} else { //The key is currently not down
		return false;
	}
}

vector<Key> KeyboardManager::GetAllPressedKeys(){
	vector<Key> l;

	for (pair<Key, bool> kvp : KeyStates) {
		if (IsPressed(kvp.first)) {
			l.push_back(kvp.first);
		}
	}

	return l;
}

bool KeyboardManager::IsReleased(Key key){
	if (ContainsKey(PrevKeyStates, key) && !PrevKeyStates[key]) { //If it was previously up
		return false;
	} else if (ContainsKey(KeyStates, key) && !KeyStates[key]) { //Previously down & is currently up
		return true;
	} else { //The key is currently not up
		return false;
	}
}

vector<Key> KeyboardManager::GetAllReleasedKeys(){
	vector<Key> l;

	for (pair<Key, bool> kvp : KeyStates) {
		if (IsReleased(kvp.first)) {
			l.push_back(kvp.first);
		}
	}

	return l;
}

bool KeyboardManager::ContainsKey(map<WPARAM, bool> keymap, WPARAM key){
	return keymap.find(key) != keymap.end();
}
